package com.xiaouyudeguang.common.utils;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.xiaouyudeguang.common.cache.RedisCache;
import com.xiaouyudeguang.common.config.SmsConfig;
import com.xiaouyudeguang.common.dto.SmsDto;
import com.xiaouyudeguang.common.exception.BusinessException;
import com.xiaouyudeguang.common.validate.SmsRequestValidate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class CodeUtils {

    private static final String CACHE_KEY = "sms:verify:%s:%s:%s";

    private static SmsConfig smsConfig;

    public CodeUtils(@Autowired(required = false) SmsConfig smsConfig,
                     @Autowired(required = false) SmsRequestValidate smsRequestValidate) {
        CodeUtils.smsConfig = smsConfig;
    }

    public static SendSmsResponse send(String tenantId, String appId, String channel, String phone) throws Exception {
        String cacheKey = String.format(CACHE_KEY, appId, channel, phone);
        String templateCode = smsConfig.getTemplate().get(channel);
        if (StringUtils.isBlank(templateCode)) {
            throw new BusinessException("暂不支持发送验证码");
        }
        String cacheValue = RedisCache.get(cacheKey);
        if (!smsConfig.getLocalDev() && cacheValue != null && !cacheValue.isEmpty()) {
            throw new BusinessException("请勿重复发送验证码");
        }
        String verifyCode = (int) (Math.random() * 9000 + 1000) + "";
        try {
            RedisCache.set(cacheKey, verifyCode, 3, TimeUnit.MINUTES);
            return SmsUtils.send(tenantId, appId, templateCode, SmsDto.builder().phone(phone).templateParam(MapModel.get("code", verifyCode)).build());
        } catch (Exception e) {
            RedisCache.delete(cacheKey);
            throw e;
        }
    }

    public static boolean validate(String tenantId, String appId, String channel, String phone, String code) throws Exception {
        String cacheKey = String.format(CACHE_KEY, appId, channel, phone);
        String cacheValue = RedisCache.get(cacheKey);
        if (StringUtils.isBlank(cacheValue) || !code.equals(cacheValue)) {
            throw new BusinessException("验证码不匹配或已过期");
        }
        if (!smsConfig.getLocalDev()) {
            RedisCache.delete(cacheKey);
        }
        return true;
    }
}
